
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
 
 /* sockets */
 #include <sys/types.h>
 #include <sys/socket.h>
 
 /* for non blocking */
 #include <fcntl.h>
 
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
 #include <pthread.h>
 
 /* for libevent */
 #include <event.h>
 #include <time.h>
 // #define MAKE_UDP 1
 
 void readEv(int fd, short event, void* arg) {
 	int len;
 	char *buf = malloc(256);
 	struct event *ev = arg;
 	//printf("DNS_read called with %s fd: %d, event: %d\n",
 	//	event_get_method(), fd, event);
 
 	//bzero(buf,sizeof(buf));
	len = read(fd, buf, sizeof(buf));
 	if (len <0) {
 		perror("recv");
		close(fd);
 		return;
 	} else if (len == 0) {
 		printf("Connection Closed\n");
		close(fd);
 		return;
 	}
 	
 	buf[len] = '\0';
 	
 	printf("READ: %s\n", buf);
	
	write(fd, buf, sizeof(buf));
 }

 void on_write(int fd, short event, void* arg){

 }
 
void connection_time(int fd, short event, struct event *arg)
{
    char buf[32];
    struct tm t;
    time_t now;

    time(&now);
    localtime_r(&now, &t);
    asctime_r(&t, buf);

    write(fd, buf, strlen(buf));
    shutdown(fd, SHUT_RDWR);

    free(arg);
}

void connection_accept(int fd, short event, void *arg)
{
    /* for debugging */
    fprintf(stderr, "%s(): fd = %d, event = %d.\n", __func__, fd, event);

    /* Accept a new connection. */
    struct sockaddr_in s_in;
    socklen_t len = sizeof(s_in);
    int ns = accept(fd, (struct sockaddr *) &s_in, &len);
    if (ns < 0) {
        perror("accept");
        return;
    }

    /* Install time server. */
    struct event *ev = malloc(sizeof(struct event));
    event_set(ev, ns, EV_WRITE, (void *) readEv, ev);
    event_add(ev, NULL);
}

 int main() {
 	int sock;
 	int yes = 1;
 	int len = sizeof(struct sockaddr);
 	struct sockaddr_in addr;
 
 	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 		perror("socket");
 		return 1;
 	}
 	
 	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) < 0) {
 		perror("setsockopt");
 		return 1;
 	}
 	
 	addr.sin_family = AF_INET;
 	addr.sin_port = htons(5555);
 	addr.sin_addr.s_addr = INADDR_ANY;
 	bzero(&(addr.sin_zero), 8);
 	
 	if (bind(sock, (struct sockaddr*)&addr, len) < 0) {
 		perror("bind");
 		return 1;
 	}

	if (listen(sock,3) < 0) {
		perror("listen!");
		return 1;
	}
 	
 	printf("Listening now...\n");
 	
 	struct event ev;
 	
 	event_init();
 	
 	event_set(&ev, sock, EV_READ | EV_PERSIST, connection_accept, &ev);
 	
 	event_add(&ev, NULL);
 	
 	event_dispatch();
 	
 	printf("Done!\n");
 	return 1;
 } 
